package com.yanqu.road.web.controller.usercenter.newadmin;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.dao.impl.servercenter.CrossServerInfoDaoImpl;
import com.yanqu.road.entity.admin.AdminResult;
import com.yanqu.road.entity.admin.AdminResult2;
import com.yanqu.road.entity.servercenter.CrossServerInfo;
import com.yanqu.road.entity.servercenter.ProcessInfo;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.web.ICrossWebService;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.http.HttpHelper;
import com.yanqu.road.web.WebServer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 *
 */
@RestController
@RequestMapping("/usercenter/admin")
public class CenterConfigReloadController {

    private static Logger logger = LogManager.getLogger(CenterConfigReloadController.class.getName());

    /**
     * 40.1 加载配置
     */
    @ResponseBody
    @RequestMapping(value = "serverMgrReload", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public String serverMgrReload(HttpServletRequest request, @RequestBody JSONObject jsonObject) {

        int channelId = jsonObject.getIntValue("channelId");

        JSONArray serverIdArray = jsonObject.getJSONArray("serverIdList");

        String clazzName = jsonObject.getString("clazzName");

        List<Long> serverIdList = new ArrayList<>();
        for (int i = 0; i < serverIdArray.size(); i++) {
            serverIdList.add(serverIdArray.getLongValue(i));
        }
        AdminResult result = AdminResult.defaultInstance();
        ExecutorService webExecutor = WebServer.getWebExecutor();
        List<ServerInfo> channelServerList = ServerListMgr.getChannelServerList(channelId);
        if (channelServerList.size() > 0) {
            List<Future> futureList = new ArrayList<>();
            Map<String, String> paramMap = getStringStringMap(clazzName);
            for (ServerInfo serverInfo : channelServerList) {
                if (!serverIdList.contains(serverInfo.getServerId())) {
                    continue;
                }
                Future future = webExecutor.submit(new Callable<Boolean>() {
                    @Override
                    public Boolean call() throws Exception {
                        String response = "";
                        try {
                            response = HttpHelper.doPost(serverInfo.getWebServerUrl() + "/reloadMgr", paramMap, "UTF-8");
                            JSONObject jsonObject = JSONObject.parseObject(response);
                            if (jsonObject.getIntValue("status") == 0) {
                                ServerListMgr.getLogger().error("error, 区服 {} 刷新失败", serverInfo.getServerId());
                                result.getData().put(String.valueOf(serverInfo.getServerId()), false);
                            }
                        } catch (Exception ex) {
                            ServerListMgr.getLogger().error("error, {} {}", response == null ? "" : response, ex.toString());
                        }
                        return true;
                    }
                });
                futureList.add(future);
            }
            if (!futureList.isEmpty()) {
                for (Future future : futureList) {
                    try {
                        future.get(15, TimeUnit.SECONDS);
                    } catch (InterruptedException | ExecutionException | TimeoutException e) {
                        logger.error("", e);
                    }
                }
            }
        }
        return result.toJsonString();
    }


    /**
     * 45.1 加载配置
     */
    @ResponseBody
    @RequestMapping(value = "crossMgrReload", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public String crossMgrReload(HttpServletRequest request, @RequestBody JSONObject jsonObject) {

        int channelId = jsonObject.getIntValue("channelId");

        JSONArray serverIdArray = jsonObject.getJSONArray("crossServerIdList");

        String clazzName = jsonObject.getString("clazzName");

        List<Integer> serverIdList = new ArrayList<>();
        for (int i = 0; i < serverIdArray.size(); i++) {
            serverIdList.add(serverIdArray.getIntValue(i));
        }
        AdminResult adminResult = AdminResult.defaultInstance();
        ExecutorService webExecutor = WebServer.getWebExecutor();

        List<CrossServerInfo> serverInfoList = new CrossServerInfoDaoImpl().getAllChannelCrossServerInfo(channelId);
        serverInfoList.removeIf(next -> (!serverIdList.contains(next.getCrossServerId())));

        if(serverInfoList.isEmpty()){
            return adminResult.setMsg("参数错误").setCode(-1).toJsonString();
        }

        List<ProcessInfo> processInfoList = new ArrayList<>();

        for (CrossServerInfo crossServerInfo : serverInfoList) {
            for (ProcessInfo processInfo : crossServerInfo.getProcessInfoList()) {
                if(processInfo.getServerName().equals("cross_server")) {
                    processInfoList.add(processInfo);
                }
            }
        }

        try {
            //遍历异步通知活动跨服
            CountDownLatch countDownLatch = new CountDownLatch(processInfoList.size());
            JSONObject param = new JSONObject();
            param.put("content", clazzName);
            for (ProcessInfo processInfo : processInfoList) {
                webExecutor.execute(() -> {
                    try {
                        String url = "http://" + processInfo.getAddress() + ":" + processInfo.getAdminPort() + "/crossws?wsdl";
                        QName qName = new QName("http://webservice.server.road.yanqu.com/", "GrossWebServiceService");
                        Service service = Service.create(new URL(url), qName);
                        ICrossWebService crossWebService = service.getPort(ICrossWebService.class);
                        String resp = crossWebService.executeAdminOperate("AgentReload|reloadMgr", param.toJSONString(), "Yanqu123");
                        JSONObject result = JSONObject.parseObject(resp);
                        int status = result.getInteger("status");
                        if (status != 1) {
                            adminResult.getData().put(String.valueOf(processInfo.getServerId()), false);
                        }
                    } catch (Exception e) {
                        logger.error("", e);
                        adminResult.getData().put(String.valueOf(processInfo.getServerId()), false);
                    } finally {
                        countDownLatch.countDown();
                    }
                });
            }
            //等待
            if (!countDownLatch.await(30, TimeUnit.SECONDS)) {
                ServerListMgr.getLogger().error("刷新超时");
            }
        } catch (Exception e) {
            logger.error("", e);
        }
        return adminResult.toJsonString();
    }


    private Map<String, String> getStringStringMap (String clazzName){
        Map<String, String> paramMap = new HashMap<>();
        JSONObject param = new JSONObject();
        param.put("name", clazzName);
        JSONObject param1 = new JSONObject();
        param1.put("param", param);
        paramMap.put("param", param1.toJSONString());
        return paramMap;
    }

    /**
     * 45.2 跨服列表
     */
    @ResponseBody
    @RequestMapping(value = "crossServerList", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public String crossServerList(HttpServletRequest request, @RequestBody JSONObject jsonObject) {
        AdminResult adminResult = AdminResult.defaultInstance();
        int channelId = jsonObject.getIntValue("channelId");
        List<CrossServerInfo> serverInfoList = new CrossServerInfoDaoImpl().getAllChannelCrossServerInfo(channelId);
        adminResult.getData().put("total", serverInfoList.size());
        JSONArray array = new JSONArray();
        for (CrossServerInfo crossServerInfo : serverInfoList) {
            JSONObject object = new JSONObject();
            object.put("crossServerId", crossServerInfo.getCrossServerId());
            array.add(object);
        }
        adminResult.getData().put("row", array);
        return adminResult.toJsonString();
    }
}
